/*
 * Copyright (c) 2024 Huawei Technologies Co., Ltd.
 * openFuyao is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */

package uutil

import (
	"errors"
	"testing"
	"time"
)

func TestGenerateID(t *testing.T) {
	// Test case 1: Generate a new ID
	id1 := GenerateID()
	if id1 == "" {
		t.Errorf("Test case 1 failed: GenerateID() returned an empty string")
	}

	// Test case 2: Generate multiple IDs and check if they are unique
	id2 := GenerateID()
	if id2 == "" {
		t.Errorf("Test case 2 failed: GenerateID() returned an empty string")
	}
	if id1 == id2 {
		t.Errorf("Test case 2 failed: Generated IDs are not unique")
	}

	// Test case 3: Generate IDs at different times and check if they are unique
	time.Sleep(1 * time.Second)
	id3 := GenerateID()
	if id3 == "" {
		t.Errorf("Test case 3 failed: GenerateID() returned an empty string")
	}
	if id1 == id3 || id2 == id3 {
		t.Errorf("Test case 3 failed: Generated IDs are not unique")
	}
}

func TestValidateID(t *testing.T) {
	// 测试ID为空的情况
	id1 := ""
	err1 := ValidateID(id1)
	if err1 == nil {
		t.Errorf("Expected error for empty id, but got nil")
	}

	// 测试ID长度不为标准长度的情况
	id2 := "1234567890"
	err2 := ValidateID(id2)
	if err2 == nil {
		t.Errorf("Expected error for id length not equal to standard length, but got nil")
	}

	// 测试ID长度为标准长度的情况
	id3 := "01234567890123456789012345678901234567890123456789012345"
	err3 := ValidateID(id3)
	if err3 != nil {
		t.Errorf("Expected no error for valid id, but got %v", err3)
	}
}

func TestValidateUTC(t *testing.T) {
	// 测试时间格式正确的情况
	timeStr1 := "2022-01-01T00:00:00Z"
	err1 := ValidateUTC(timeStr1)
	if err1 != nil {
		t.Errorf("Expected no error for valid UTC time, but got %v", err1)
	}

	// 测试时间格式错误的情况
	timeStr2 := "2022-01-01 00:00:00"
	err2 := ValidateUTC(timeStr2)
	if err2 == nil {
		t.Errorf("Expected error for invalid UTC time, but got nil")
	}
}

func TestValidateStep(t *testing.T) {
	tests := []struct {
		startUTC string
		endUTC   string
		stepStr  string
		expected error
	}{
		{
			startUTC: "2022-01-01T00:00:00Z",
			endUTC:   "2022-01-01T00:00:00Z",
			stepStr:  "1",
			expected: errors.New("end time is less than start time plus step"),
		},
		{
			startUTC: "2022-01-01T00:00:00Z",
			endUTC:   "2022-01-01T00:00:01Z",
			stepStr:  "1",
			expected: nil,
		},
		{
			startUTC: "2022-01-01T00:00:00Z",
			endUTC:   "2022-01-01T00:00:01Z",
			stepStr:  "2",
			expected: errors.New("end time is less than start time plus step"),
		},
		{
			startUTC: "2022-01-01T00:00:00Z",
			endUTC:   "2022-01-01T00:00:00Z",
			stepStr:  "0",
			expected: errors.New("invalid step duration"),
		},
		{
			startUTC: "2022-01-01T00:00:00Z",
			endUTC:   "2022-01-01T00:00:00Z",
			stepStr:  "-1",
			expected: errors.New("invalid step duration"),
		},
	}
	for _, test := range tests {
		err := ValidateStep(test.startUTC, test.endUTC, test.stepStr)
		if test.expected == nil && err != nil {
			t.Errorf("Expected no error for valid step, but got %v", err)
		}
		if errors.Is(err, nil) && test.expected != nil {
			t.Errorf("Expected Validate to return error %v, but got %v", test.expected, err)
		}
		if err != nil && err.Error() != test.expected.Error() {
			t.Errorf("Expected Validate to return error %v, but got %v", test.expected, err)
		}
	}
}

func TestValidateHost(t *testing.T) {
	tests := []struct {
		uri      string
		expected error
	}{
		{
			uri:      "http://localhost:8080",
			expected: nil,
		},
		{
			uri:      "http://localhost:8080/",
			expected: errors.New("invalid host format"),
		},
		{
			uri:      "http://localhost:8080/path",
			expected: errors.New("invalid host format"),
		},
	}

	for _, test := range tests {
		err := ValidateHost(test.uri)
		if test.expected == nil && err != nil {
			t.Errorf("Expected no error for valid step, but got %v", err)
		}
		if errors.Is(err, nil) && test.expected != nil {
			t.Errorf("Expected Validate to return error %v, but got %v", test.expected, err)
		}
		if err != nil && err.Error() != test.expected.Error() {
			t.Errorf("Expected Validate to return error %v, but got %v", test.expected, err)
		}
	}
}

func TestValidateDisplayName(t *testing.T) {
	tests := []struct {
		displayName string
		maxLength   int
		expected    error
	}{
		{
			displayName: "ValidName",
			maxLength:   10,
			expected:    nil,
		},
		{
			displayName: "",
			maxLength:   10,
			expected:    errors.New("displayName is empty"),
		},
		{
			displayName: "ThisNameIsTooLong",
			maxLength:   10,
			expected:    errors.New("displayName is too long"),
		},
	}

	for _, test := range tests {
		err := ValidateDisplayName(test.displayName, test.maxLength)
		if test.expected == nil && err != nil {
			t.Errorf("Expected no error for valid step, but got %v", err)
		}
		if errors.Is(err, nil) && test.expected != nil {
			t.Errorf("Expected Validate to return error %v, but got %v", test.expected, err)
		}
		if err != nil && err.Error() != test.expected.Error() {
			t.Errorf("Expected Validate to return error %v, but got %v", test.expected, err)
		}
	}
}
